package viroyal.com.base.util;

import android.util.Log;

import com.suntiago.baseui.utils.log.Slog;

import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.LinkedList;
import java.util.Queue;

import viroyal.com.base.MyApp;
import viroyal.com.base.listener.IdentifyCardListener;
import viroyal.com.base.net.entity.AssistBean;
import viroyal.com.base.net.entity.ComBean;

public class IdentifyCard {

    private SerialControl ComA;//4个串口
    private DispQueueThread DispQueue;//刷新显示线程
    private AssistBean AssistData;//用于界面数据序列化和反序列化
    private IdentifyCardListener identifyCardListener;

    public IdentifyCard() {
        ComA = new SerialControl();
        DispQueue = new DispQueueThread();
        DispQueue.start();
        AssistData = new AssistBean();
        setControls();
    }

    private void setControls() {
        ComA.setPort(AssistData.sPort);
        ComA.setBaudRate(AssistData.sBaudRate);
        OpenComPort(ComA);
    }

    //串口控制类
    private class SerialControl extends SerialHelper {

        public SerialControl() {}

        @Override
        protected void onDataReceived(final ComBean ComRecData) {
            //数据接收量大或接收时弹出软键盘，界面会卡顿,可能和6410的显示性能有关
            //直接刷新显示，接收数据量大时，卡顿明显，但接收与显示同步。
            //用线程定时刷新显示可以获得较流畅的显示效果，但是接收数据速度快于显示速度时，显示会滞后。
            //最终效果差不多-_-，线程定时刷新稍好一些。
            DispQueue.AddQueue(ComRecData);//线程定时刷新显示(推荐)
        }
    }

    //刷新显示线程
    private class DispQueueThread extends Thread {
        private Queue<ComBean> QueueList = new LinkedList<>();

        @Override
        public void run() {
            super.run();
            while (!isInterrupted()) {
                final ComBean ComData;
                while ((ComData = QueueList.poll()) != null) {
                    DispRecData(ComData);
                    try {
                        Thread.sleep(100);//显示性能高的话，可以把此数值调小。
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }

        public synchronized void AddQueue(ComBean ComData) {
            QueueList.add(ComData);
        }
    }

    //----------------------------------------------------显示接收数据
    private void DispRecData(ComBean ComRecData) {
        Slog.d("IdentifyCard", "DispRecData: " + new String(ComRecData.bRec));
        identifyCardListener.cardNumber(ComRecData);
    }

    //----------------------------------------------------关闭串口
    public void CloseComPort() {
        if (ComA != null) {
            ComA.stopSend();
            ComA.close();
        }
    }

    //----------------------------------------------------打开串口
    private void OpenComPort(SerialHelper ComPort) {
        try {
            ComPort.open();
        } catch (SecurityException e) {
            Slog.d("IdentifyCard", "OpenComPort: 打开串口失败:没有串口读/写权限!");
        } catch (IOException e) {
            Slog.d("IdentifyCard", "OpenComPort: 打开串口失败:未知错误!");
        } catch (InvalidParameterException e) {
            Slog.d("IdentifyCard", "OpenComPort: 打开串口失败:参数错误!");
        }
    }

    public void CardNumber(IdentifyCardListener identifyCardListener) {
        this.identifyCardListener = identifyCardListener;
    }
}
